package com.easy.thread;

import com.easy.thread.handler.EasyRejectedExecutionHandler;

import java.util.concurrent.*;

/**
 * @Packge com.easy.thread
 * @Autor linNaibin
 * @Description
 * @Version 1.0
 * @Date 2021/1/12 16:39
 */
public class TheadPoolServer {

    private final static int CORE_POOL_SIZE = 2;
    private final static int MAXIMUM_POOL_SIZE = 4;
    private final static long KEEP_ALIVE_TIME = 400l;
    private final static int MAX_TASK_LENGTH = 10;

    /*
        任务队列
     */
    private static BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(MAX_TASK_LENGTH);

    // ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。  【默认】
    // ThreadPoolExecutor.DiscardPolicy：也是丢弃任务，但是不抛出异常。
    // ThreadPoolExecutor.DiscardOldestPolicy：丢弃线称队列的旧的任务，将新的任务添加
    // ThreadPoolExecutor.CallerRunsPolicy：由调用线程处理该任务 【谁调用，谁处理】
    // private static final RejectedExecutionHandler DEFAULT_HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();
    private static final RejectedExecutionHandler DEFAULT_HANDLER = new EasyRejectedExecutionHandler();

    private static ExecutorService EXECUTOR_SERVICE;


    private static final ThreadFactory THREAD_FACTORY = new ThreadFactory() {
        @Override
        public Thread newThread(Runnable r) {
            Thread thread = new Thread(r);
            thread.setName("模型算法线程【" + thread.getId() + "】");
            return thread;
        }
    };

    private TheadPoolServer() {
        init();
    }

    private void init() {
        // 创建线程池 ， 参数含义 ：（核心线程数，最大线程数，加开线程的存活时间，时间单位，任务队列长度）
        EXECUTOR_SERVICE = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.MILLISECONDS, workQueue, THREAD_FACTORY, DEFAULT_HANDLER);
    }

    private static class ServerHolder {
        private static final TheadPoolServer INSTANCE = new TheadPoolServer();
    }

    public static TheadPoolServer getInstance() {
        return ServerHolder.INSTANCE;
    }

    public void submit(Runnable runnable) {
        EXECUTOR_SERVICE.submit(runnable);
    }


    public static void main(String[] args) {

        final CountDownLatch latch = new CountDownLatch(30);

        System.out.println("start ... ");
        TheadPoolServer server = TheadPoolServer.getInstance();

        for (int i = 0; i < 31; i++) {
            Runnable runnable = new EasyRunnable(i + "xxx", latch);
            server.submit(runnable);
        }


        try {
            latch.await();
            //关闭线程池

            EXECUTOR_SERVICE.shutdown();
            System.out.println("shut down ");

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(" end ...");


    }

}
